﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Configuration;

namespace TimeManagementSystem
{
    
    public class DAO
    {
        protected DataBaseAdapterDataContext context;

        public DAO()
        {
            context = new DataBaseAdapterDataContext(ConfigurationManager.ConnectionStrings["TMSConnectionString"].ConnectionString);
        }

        public List<User> GetAllUsers()
        {
            return context.Users.ToList();
        } 

        public string GetUserStatus(string login)
        {
            var user = SearchUser(login);
            if (user != null)
                return user.Status;
            return null;
        }

        public User GetUserById(int userId)
        {
            return context.Users.FirstOrDefault(us => us.Id == userId);
        }

        public User GetUserBySessionId(string sessionId)
        {
            return context.Users.FirstOrDefault(us => us.SessionId == sessionId);
        }

        public User AuthorizeUser(string login, string password)
        {
            return (from users in context.Users
                where users.Login == login &&
                      users.Password == password
                select users).FirstOrDefault();
        }

        public List<Goal> GetAllGoals()
        {
            return context.Goals.ToList();
        }

        public Goal GetGoalById(int goalId)
        {
            return context.Goals.FirstOrDefault(goal => goal.Id == goalId);
        }

        public List<Task> GetAllTasksInGoal(int goalId)
        {
            return (
                from task in context.Tasks
                where task.Goal == goalId
                select task
                ).ToList();
        }

        public List<Task> GetTasksCreatedByUser(int id)
        {
            return (from tasks in context.Tasks
                    where tasks.CreatedBy == id
                    select tasks).ToList();
        }

        public List<Task> GetAllTasksAssignedToUser(int id)
        {
            return (from tasks in context.Tasks
                    where tasks.AssignedTo == id
                    select tasks).ToList();
        }

        public Task GetTaskById(int taskId)
        {
            return context.Tasks.FirstOrDefault(task => task.Id == taskId);
        }

        public List<Bug> GetAllBugsInTask(int taskId)
        {
            return (
                from bug in context.Bugs
                where bug.Task == taskId
                select bug
                    ).ToList();
        }

        public List<Comment> GetAllCommentsInBug(int bugId)
        {
            return (
                from comments in context.Comments
                where comments.Bug == bugId
                select comments
                    ).ToList();
        } 

        public string GetBugStatus(int bugId)
        {
            var bug = (
               from bugs in context.Bugs
               where bugs.Id == bugId
               select bugs).FirstOrDefault();
            if (bug != null) 
                return bug.Status;
            return null;
                  
        }

        public Goal SearchGoal(string goalName, int createdBy)
        {
            return (from goals in context.Goals
                where goals.Name == goalName &&
                      goals.CreatedBy == createdBy
                select goals).FirstOrDefault();
        }

        public void AddGoal(string goalName, int createdBy)
        {
            var newGoal = new Goal
            {
                Name = goalName,
                CreatedBy = createdBy
            };
            context.Goals.InsertOnSubmit(newGoal);
            context.SubmitChanges();
        }

        public void RemoveGoal(Goal goalToRemove)
        {
            context.Goals.DeleteOnSubmit(goalToRemove);
            context.SubmitChanges();
        }

        public void RenameGoal(Goal goal, string newGoalName)
        {
            goal.Name = newGoalName;
            context.SubmitChanges();
        }

        public User SearchUser(string login)
        {
            return context.Users.FirstOrDefault(us => us.Login == login);
        }

        public void AddUser(string name, string surname, string patronymic, string email, string login, string password, string status)
        {
            var newUser = new User
            {
                Name = name,
                Surname = surname,
                Patronymic = patronymic,
                Email = email,
                Login = login,
                Password = password,
                Status = status
            };
            context.Users.InsertOnSubmit(newUser);
            context.SubmitChanges();
        }

        public void RemoveUser(User userToRemove)
        {
            context.Users.DeleteOnSubmit(userToRemove);
            context.SubmitChanges();
        }

        public void ChangeUserStatus(User user, string newStatus)
        {
            user.Status = newStatus;
            context.SubmitChanges();
        }

        public void EditUser(User user, string name, string sname, string patronymic, string email, string login, string status)
        {
            user.Name = name;
            user.Surname = sname;
            user.Patronymic = patronymic;
            user.Email = email;
            user.Login = login;
            user.Status = status;
            context.SubmitChanges();
        }

        public void SetUserSessionId(User user, string sessionId)
        {
            user.SessionId = sessionId;
            context.SubmitChanges();
        }

        public Task SearchTask(int goalId, string taskName) 
        {
            return (from tasks in context.Tasks
                where tasks.Goal == goalId &&
                      tasks.Name == taskName
                select tasks).FirstOrDefault();
        }

        public void AddTask(int goalId, string taskName, string taskDescription, string status,
            string priority, DateTime startDate, DateTime finishDate, int assignedTo, int createdBy)
        {
            var newTask = new Task
            {
                Name = taskName,
                Goal = goalId,
                Status = status,
                Priority = priority,
                StartDate = startDate,
                FinishDate = finishDate,
                Description = taskDescription
            };
            if (assignedTo != 0)
                newTask.AssignedTo = assignedTo;
            if (createdBy != 0)
                newTask.CreatedBy = createdBy;
            context.Tasks.InsertOnSubmit(newTask);
            context.SubmitChanges();
        }

        public void RemoveTask(Task task)
        {
            context.Tasks.DeleteOnSubmit(task);
            context.SubmitChanges();
        }

        public void ChangeTask(Task task, string taskName, string status,
            string priority, DateTime startDate, DateTime finishDate, int assignedTo)
        {
            task.Name = taskName;
            task.Status = status;
            task.Priority = priority;
            task.StartDate = startDate;
            task.FinishDate = finishDate;
            task.AssignedTo = assignedTo;
            context.SubmitChanges();
        }

        public void ChangeTaskPriority(Task task, string priority)
        {
            task.Priority = priority;
            context.SubmitChanges();
        }

        public void ChangeTaskStatus(Task task, string status) 
        {
            task.Status = status;
            context.SubmitChanges();
        }

        public Bug SearchBug(int taskId,string bugName) 
        {
            return (from bugs in context.Bugs
                    where bugs.Task == taskId &&
                          bugs.Name == bugName
                    select bugs).FirstOrDefault();
        }

        public int GetBugNumber(int taskId)
        {
            if (GetAllBugsInTask(taskId).Count == 0)
                return 0;
            return (
                from bugs in context.Bugs
                where bugs.Task == taskId
                select bugs.Number).Max();
        }

        public void AddBug(Task task, string bugName, string description, string type,
            string category, string version, int reportedBy)
        {
            var newBug = new Bug
            {
                Task = task.Id,
                Number = GetBugNumber(task.Id) + 1,
                Name = bugName,
                Description = description,
                Type = type,
                Category = category,
                ReportedOn = DateTime.Today,
                ReportedBy = reportedBy,
                Status = "New",
                UpdatedOn = DateTime.Today,
                LastUpdateBy = reportedBy,
                Version = version
            };
            context.Bugs.InsertOnSubmit(newBug);
            context.SubmitChanges();
        }

        public void RemoveBug(Bug bugToDelete)
        {
            context.Bugs.DeleteOnSubmit(bugToDelete);
            context.SubmitChanges();
        }

        public void ChangeBug(Bug bug, string bugName, string type,
            string category, string version, string status, int updatedBy)
        {
            bug.Name = bugName;
            bug.Type = type;
            bug.Category = category;
            bug.Status = status;
            bug.UpdatedOn = DateTime.Today;
            bug.LastUpdateBy = updatedBy;
            bug.Version = version;
            context.SubmitChanges();
        }

        public void ChangeBugStatus(Bug bug, string newStatus, int updatedBy)
        {
            bug.Status = newStatus;
            bug.LastUpdateBy = updatedBy;
            bug.UpdatedOn = DateTime.Today;
            context.SubmitChanges();
        }

        public Comment SearchComment(int bugId, string commentName)
        {
            return (from comments in context.Comments
                    where comments.Bug == bugId &&
                          comments.Name == commentName
                    select comments).FirstOrDefault();
        }

        public void AddComment(int bugId, string name, string description, int createdBy)
        {
            var comment = new Comment
            {
                Name = name,
                Description = description,
                Bug = bugId,
                CreatedBy = createdBy,
                Date = DateTime.Today
            };
            context.Comments.InsertOnSubmit(comment);
            context.SubmitChanges();
        }

        public void RemoveComment(Comment comment)
        {
            context.Comments.DeleteOnSubmit(comment);
            context.SubmitChanges();
        }

        public void ChangeComment(Comment comment, string name)
        {
            comment.Name = name;
            comment.Date = DateTime.Today;
            context.SubmitChanges();
        }
    }
}